package cn.hls.until;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.util.StringUtils;

import com.chinamobile.openmas.client.Sms;

import cn.hls.exception.BussinessException;

/**
 * @fileName: GenericsUtils.java
 * @descrption: 通用工具类
 * @author : yinghui.zhang
 * @Email: uuhui@163.com
 * @date 2015-4-7
 * @version 1.0
 */
public class GenericsUtils {
	/**
	 * 通过反射, 获得定义Class时声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
	 * 
	 * @param clazz
	 *            clazz The class to introspect
	 * @param index
	 *            the Index of the generic ddeclaration,start from 0.
	 * @return the index generic declaration, or Object.class if cannot be
	 *         determined
	 */
	// private static Logger log=Logger.getLogger(GenericsUtils.class);
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Class<Object> getSuperClassGenricType(final Class clazz,
			final int index) {

		// 返回表示此 Class 所表示的实体（类、接口、基本类型或 void）的直接超类的 Type。
		Type genType = clazz.getGenericSuperclass();

		if (!(genType instanceof ParameterizedType)) {
			return Object.class;
		}
		// 返回表示此类型实际类型参数的 Type 对象的数组。
		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

		if (index >= params.length || index < 0) {
			return Object.class;
		}
		if (!(params[index] instanceof Class)) {
			return Object.class;
		}

		return (Class) params[index];
	}

	/**
	 * 根据指定的时间获取该下一年的时间
	 * 
	 * @param currentTime
	 *            　指定时间
	 * @return Date
	 */
	@SuppressWarnings("static-access")
	public static Date getNextYearTime(Date currentTime) {
		Calendar c = null;
		try {
			c = Calendar.getInstance();
			if (currentTime != null) {
				c.setTime(currentTime);
			}
			// 获取下一年的时间
			c.add(c.YEAR, 1);
			return c.getTime();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 当前时间前几个月计算
	 * 
	 * @param currentTime
	 *            当前时间
	 * @param diff
	 *            时间差
	 * @return　Date
	 */
	@SuppressWarnings("static-access")
	public static Date getPreMonthTime(Date currentTime, int diff) {
		Calendar c = null;
		try {
			c = Calendar.getInstance();
			if (currentTime != null) {
				c.setTime(currentTime);
			}
			// 获取上一年的时间
			c.add(c.MONTH, -diff);
			return c.getTime();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static Date getPreDateTime(Date currentTime, int diff) {
		Calendar c = null;
		try {
			c = Calendar.getInstance();
			if (currentTime != null) {
				c.setTime(currentTime);
			}
			// 获取上一年的时间
			c.add(c.DATE, -diff);
			return c.getTime();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * 当前时间前一个月第1天
	 * 
	 * @return　Date
	 */
	public static Date getFirstDayOfPreMonth() {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, -1);
		c.set(Calendar.DAY_OF_MONTH, 1);
		return c.getTime();
	}

	/**
	 * 获取当前时间前一个月的最后一天
	 * 
	 * @return
	 */
	public static Date getLastDayOfPreMonth() {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, -1);
		c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
		return c.getTime();
	}

	/**
	 * 加密
	 * 
	 * @param str
	 *            需要加密的字符串
	 * @param salt
	 *            盐值
	 * @return String
	 */
	public static String encrypt(String str, String salt) {
		return new Md5PasswordEncoder().encodePassword(str, salt);
	}

	/** 浮点数相减运算 **/
	public static float floatSub(Float num1, Float num2) {
		BigDecimal n1 = new BigDecimal(Float.toString(num1));
		BigDecimal n2 = new BigDecimal(Float.toString(num2));
		return n1.subtract(n2).floatValue();
	}

	/** 浮点数相加运算 **/
	public static float floatAdd(Float num1, Float num2) {
		BigDecimal n1 = new BigDecimal(Float.toString(num1));
		BigDecimal n2 = new BigDecimal(Float.toString(num2));
		return n1.add(n2).floatValue();
	}

	/**
	 * @param date
	 *            日期
	 * @param pattern
	 *            转换方式
	 * @return String
	 * @throws Exception
	 */
	public static String dateFormat(Date date, String pattern) throws Exception {
		DateFormat dsf = new SimpleDateFormat(pattern);
		return dsf.format(date);
	}
	
	/**
	 * 设置日期格式化
	 * @param pattern 格式化方式
	 * @return DateFormat
	 * @throws Exception 
	 */
	public static DateFormat getDateFormat(String pattern)throws Exception{
		return new SimpleDateFormat(pattern);
	}
	
	/**
	 * 字符串转日期
	 * @param param 日期字符串
	 * @param pattern 转换格式
	 * @return Date
	 * @throws Exception
	 */
	public static Date StringToDate(String param,String pattern )throws Exception{
		DateFormat df=new SimpleDateFormat(pattern);
		return df.parse(param);
	}
	/**
	 * 动态调用javaBean的set方法为属性赋值
	 * @param clazz javaBean 类
	 * @param fileName 属性名
	 * @param fieldValue 属性值
	 * **/
	
	public static void invokeSetMethod(Object obj,String filedName,Object fieldValue)
	throws Exception{
		@SuppressWarnings("rawtypes")
		Class clazz=obj.getClass();
		  Field field = clazz.getDeclaredField(filedName); 
		  PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
		 String properType=  pd.getPropertyType().getSimpleName();
		 if(properType.equalsIgnoreCase("Integer")){
			fieldValue=fieldValue==null||"".equals(fieldValue)?null:Integer.valueOf(fieldValue+""); 
		 }else if(properType.equalsIgnoreCase("Long")){
			 fieldValue=fieldValue==null||"".equals(fieldValue)?null:Long.valueOf(fieldValue+"");
		 }else if(properType.equalsIgnoreCase("Boolean")){
			 fieldValue=fieldValue==null||"".equals(fieldValue)?null:Boolean.valueOf(fieldValue+"");
		 }else if(properType.equalsIgnoreCase("Date")){
			 fieldValue=fieldValue==null||"".equals(fieldValue)?null:getDateFormat("yyyy-MM-dd").parseObject(fieldValue+"");
		 }
		  Method m=pd.getWriteMethod();
		  
		  m.invoke(obj, fieldValue);
	}
	
	/**
	 * 计算时间差
	 * @param time1　时间1
	 * @param time2　时间2
	 * @return int
	 * @throws Exception 操作异常
	 */
	 public static int diffMin(String time1,String time2)throws Exception{
		 DateFormat dsf=new SimpleDateFormat("HH:mm:ss");
		 Date d1=dsf.parse(time1);
		 Date d2=dsf.parse(time2);
		 long time=  d1.getTime()-d2.getTime();
		 return (int) time/6000;
	 }
	 
	 /**
	  * 判断两个时间的大小
	  * @param time1 时间1
	  * @param time2 时间2
	  * @return int
	  * @throws Exception
	  */
	 public static long compareTime(Date time1,Date time2)throws Exception{
		 return time1.getTime()-time2.getTime();
	 }
	 
	 /**
	  * 生成加密的盐值
	  * @return String
	  * @throws Exception
	  */
	 public static String getSalt()throws Exception{
		 return new Date().getTime()+"";
	 }
	 
	 /**
	  * 调用移动端口发送短信
	  * @param phone 发送手机数组
	  * @param info 发送内容
	  * @throws Exception
	  */
	 public static Integer sendMsg(String[] phone,String info)throws Exception{
		 Sms sms = new Sms("http://nb067.openmas.net:9080/OpenMasService");
	        String extendCode = "3"; //自定义扩展代码（模块）
	        String ApplicationID= "8002001";
	        String Password = "KbeTpeSZWpuF";

	        //发送短信
	      String GateWayid = sms.SendMessage(phone, info, extendCode, ApplicationID, Password);
	     if(GateWayid!=null){
	    	 return 1;
	     }else{
	    	 return 0;
	     }
	 }
	 
	 /**
		 * 验证码校验
		 * @param jsonStr 字符串
		 * @return String 
		 * @throws Exception
		 */
		
		public static boolean valideToken(String jsonStr,String token)throws Exception{
			if(!StringUtils.hasText(token)){//验证码为空
				throw new BussinessException("验证码为空");
			}else{
				String eneryToen=token.substring(0,32);
				String salt=token.substring(32);
				if((encrypt(jsonStr+salt,null)).equals(eneryToen)){
					return true;
				}else{
					return false;
				}
			}
		}
	
}
